package com.cqc.jdk8.Jmath;

import org.junit.Test;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class BigDecimalTest {

    public static void main(String[] args) {
        BigDecimal d1 = new BigDecimal("0.1");
        d1.precision();
    }
    /**
     * 1精度丢失问题：
     * 构造方法中，参数为float double等会丢失精度。参数是String,则不会丢失精度
     * BigDecimal.valueOf(.)不会丢失精度
     * b1.subtract(b2)就是b1-b2
     */
    @Test
    public void f1() {
        BigDecimal d1 = new BigDecimal(0.1f);
        BigDecimal d2 = new BigDecimal(0.1d);
        BigDecimal d3 = new BigDecimal("0.1");
        BigDecimal d4 = BigDecimal.valueOf(0.1);
        System.out.println(d1);//0.100000001490116119384765625  精度丢失
        System.out.println(d2);//0.1000000000000000055511151231257827021181583404541015625  精度丢失
        System.out.println(d3);//0.1
        System.out.println(d4);//0.1
        System.out.println(2.0d - 1.1d);//0.8999999999999999
        System.out.println(BigDecimal.valueOf(2.0d).subtract(BigDecimal.valueOf(1.1d)));//0.9
        System.out.println(new BigDecimal("2.0").subtract(new BigDecimal("1.1")));//0.9
        System.out.println(BigDecimal.valueOf(2.0d).subtract(BigDecimal.valueOf(1.1f)));//0.899999976158142

    }

    /**
     * ROUND_UP：多余的位数不要，末尾进1
     * ROUND_DOWN：多余的位数不要，后面所有直接去除
     * ROUND_HALF_UP：根据保留数字后一位>=5进行四舍五入
     * ROUND_HALF_DOWN：根据保留数字后一位>5进行四舍五入
     */
    @Test
    public void f2() {
        BigDecimal d1 = new BigDecimal("1232");
        BigDecimal divide0 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_UP);
        BigDecimal divide1 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_DOWN);
        BigDecimal divide2 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_CEILING);
        BigDecimal divide4 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_FLOOR);
        BigDecimal divide3 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_HALF_UP);
        BigDecimal divide5 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_HALF_DOWN);
        BigDecimal divide6 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_HALF_EVEN);
//         BigDecimal divide7 = d1.divide(new BigDecimal("100"), 1, BigDecimal.ROUND_UNNECESSARY);//java.lang.ArithmeticException: Rounding necessary
        System.out.println("ROUND_UP=" + divide0);
        System.out.println("ROUND_DOWN=" + divide1);
        System.out.println("ROUND_CEILING=" + divide2);
        System.out.println("ROUND_FLOOR=" + divide3);
        System.out.println("ROUND_HALF_UP=" + divide4);
        System.out.println("ROUND_HALF_DOWN=" + divide5);
        System.out.println("ROUND_HALF_EVEN=" + divide6);
//         System.out.println(divide7);
        System.out.println("------------------------------------");

        //分>元
        BigDecimal fen = new BigDecimal("1239");//分
        BigDecimal yuan = fen.divide(new BigDecimal("100"), 2, BigDecimal.ROUND_DOWN);
        System.out.println(yuan);
        //元>分
        BigDecimal fen2 = yuan.setScale(2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
        if (fen.compareTo(fen2) == 0) {//true
            System.out.println("fen.compareTo(fen2) == 0");
        }
        if (fen.equals(fen2)) {//false
            System.out.println("fen.equals(fen2)");
        }
        System.out.println(fen2);

    }

    /**
     * toString() 显示科学计数法
     * toPlainString()转成Sting,并避免科学计数法显示
     */
    @Test
    public void f3() {
        BigDecimal a = new BigDecimal("0.000000000000001");
        //1E-15  科学计数法
        System.out.println(a.toString());
        //0.000000000000001
        System.out.println(a.toPlainString());
    }

    //setScale()不会改变原值，必须用另一个变量接收
    @Test
    public void f4() {
        BigDecimal a = new BigDecimal("0.12345");
        a.setScale(2, RoundingMode.FLOOR);
        //0.12345
        System.out.println(a);
        a = a.setScale(2, RoundingMode.FLOOR);
        //0.12
        System.out.println(a);
    }

    /**
     * BigDecimal比较大小用compareTo，不能用equals()>0, <br>
     * {@code a.compare(b)} <br>
     * >0,表示{@code a>b} <br/>
     * <0,表示{@code a<b} <br/>
     */
    @Test
    public void f5() {
        BigDecimal a = new BigDecimal("0.0");
        System.out.println(a.compareTo(BigDecimal.ZERO));//0
        System.out.println(a.equals(BigDecimal.ZERO));//false

        BigDecimal b = new BigDecimal("5.6");
        System.out.println(b.compareTo(BigDecimal.ONE));//1
        System.out.println(b.compareTo(BigDecimal.TEN));//-1
    }

}
